import wave
import sys
import soundcard

import audioop
import threading
from threading import Thread

import org.hamrepeater.goertzel.goertzel

class Mixer(Thread):

    def __init__(self):
        Thread.__init__(self)
        sndcard = soundcard.Factory()
        self.__outchannels = 5
        self.__inputchannels = 5
        
        ##setup first audio card
        self.__sndHandles = []
        for i in range(0,self.__inputchannels):
            self.__sndHandles.append(sndcard.getSoundCardHandle(i))
        
        self.__matrix = []
        list0 = [1.0, 1.0, 1.0, 1.0, 1.0]
        list1 = [1.0, 1.0, 1.0, 1.0, 1.0]
        list2 = [1.0, 1.0, 1.0, 1.0, 1.0]
        list3 = [1.0, 1.0, 1.0, 1.0, 1.0]
        list4 = [1.0, 1.0, 1.0, 1.0, 1.0]

        self.__matrix.append(list0);
        self.__matrix.append(list1);
        self.__matrix.append(list2);
        self.__matrix.append(list3);
        self.__matrix.append(list4);

        self.__lock = threading.Lock()
        
        
        
        self.__goertzel = org.hamrepeater.goertzel.goertzel.Goertzel()
        self.__power = 0
        self.__soundIn = []

    def run(self):
        while True:
            #get threading lock
            self.__lock.acquire()
            self.__soundIn = []
            for i in range(0,5): 
                self.__soundIn.append(self.__sndHandles[i].readSample(1000))
            
            
            for i in range(0, 5):
                out = audioop.mul(self.__soundIn[i], 4, 0.0)
                for j in range(0, 5):
                    tmp = audioop.mul(self.__soundIn[j], 4, self.__matrix[i][j])
                    out = audioop.add(out, tmp, 4)
                self.__sndHandles[i].writeSample(out)
                
            #release lock
            self.__lock.release()

    def setmixer(self, outNumber, inputNumber, value):
        #is index ok ?self.__inputchannels
        assert(outNumber >= 0 and outNumber < self.__outchannels)
        #has the list enough elements
        assert(inputNumber >= 0 and inputNumber < self.__inputchannels)
        
        #lock access to matrix
        self.__lock.acquire()
        
        self.__matrix[outNumber][inputNumber] = value
        
        #release lock to matrix
        self.__lock.release()
        pass
    
    def getMixerValue(self, outNumber, inputNumber):
        assert(outNumber >= 0 and outNumber < self.__outchannels)
        #has the list enough elements
        assert(inputnummer > 0 and inputnumber < self.__inputchannels)
        
        return self.__matrix[outNumber][inputNumber]
        
        pass
    
    def getPower(self, channel, sideLeft, frequency):
        self.__lock.acquire()
        if sideLeft:
            sample = audioop.tomono(self.__soundIn[channel], 4, 1.0, 0.0)
        else:
            sample = audioop.tomono(self.__soundIn[channel], 4, 0.0, 1.0)
        
        
        #release lock to matrix
        self.__lock.release()
        
        power = self.__goertzel.GetPower(sample, frequency, self.__sndHandles[channel].getSampleFrequency())
        
        return power